home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / media / objects / converte / 3dspv2 / 3ds2pov.c next >
Encoding:
C/C++ Source or Header  |  1992-05-16  |  13.0 KB  |  521 lines

  1. /*
  2.       3DS2POV.C  Copyright (c) 1992 Steve Anger and Jeff Bowermaster
  3.  
  4.       Reads a 3DS ascii save file and writes a PoV DATa file
  5.  
  6.       Version 1.2                       Written May 5/92
  7.  
  8.       Compiled with Borland C++ ver. 2.0
  9. */
  10.  
  11. #include <stdio.h>
  12. #include <math.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <ctype.h>
  16. #include "rayopt.h"
  17.  
  18. #ifdef __TURBOC__
  19. extern unsigned _stklen = 16384;  /* Large stack for recursion */
  20. #else
  21. #define huge
  22. #define far
  23. #define farmalloc(size) malloc(size)
  24. #define farfree(ptr) free(ptr)
  25. #endif
  26.  
  27. #ifndef _GNUC_
  28. #include <malloc.h>
  29. #else
  30. #include <std.h>
  31. #endif
  32.  
  33. #define MAX_MATERIAL 100
  34.  
  35. #define POV 0
  36. #define RAW 1
  37.  
  38. typedef struct
  39. {
  40.     float x, y, z;
  41. }
  42. Vector;
  43.  
  44.  
  45. /* globals */
  46. char  inname[80];
  47. char  outname[80];
  48. float smooth;
  49. int   bound;
  50. int   verbose;
  51. int   materials;
  52. int   format;
  53. char  *material[MAX_MATERIAL];
  54.  
  55. /* Prototypes */
  56. void process_args (int argc, char *argv[]);
  57. void update_materials (char *new_material);
  58. void cleanup_name (char *name);
  59. char *before (char *str, char *target);
  60. char *after (char *str, char *target);
  61. char *between (char *str, char *target1, char *target2);
  62. char *strstr();
  63.  
  64. int main (int argc, char *argv[])
  65. {
  66.     int    objects, vertices, faces, vertex_number, face_number, i,a,b,c;
  67.     char   parse, string[256], mtl[64], object[64];
  68.     float  x, y, z, tx, ty, tz, red, green, blue, lens;
  69.     float  gmin_x, gmin_y, gmin_z, gmax_x, gmax_y, gmax_z;
  70.     Vector huge *coords = NULL;
  71.     FILE   *in, *out;
  72.  
  73.     process_args (argc, argv);   /* Handle the command line args */
  74.  
  75.     if ((in = fopen (inname, "r")) == NULL) {
  76.     printf ("Cannot open input file %s!\n", inname);
  77.     exit (1);
  78.     }
  79.  
  80.     if ((out = fopen (outname, "w")) == NULL) {
  81.     printf ("Cannot open output file %s!\n", outname);
  82.     exit (1);
  83.     }
  84.  
  85.     if (format == POV) {
  86.     opt_set_dec (4);
  87.     opt_set_bound (bound);
  88.     opt_set_smooth (smooth);
  89.     opt_set_quiet (!verbose);
  90.     opt_set_fname (outname, "");
  91.     }
  92.  
  93.     objects = 0;
  94.     vertices = 0;
  95.     faces = 0;
  96.     vertex_number = 0;
  97.     face_number = 0;
  98.     materials = 0;
  99.  
  100.     printf("Output to:   %s\n",outname);
  101.     printf("\nPlease wait; Processing...\n");
  102.  
  103.     if (format == POV) {
  104.     fprintf (out, "#include \"colors.dat\"\n");
  105.     fprintf (out, "#include \"shapes.dat\"\n");
  106.     fprintf (out, "#include \"textures.dat\"\n\n");
  107.     }
  108.  
  109.     while (fgets (string, 256, in) != NULL) {
  110.     parse = string[0];
  111.  
  112.     switch (parse) {
  113.         case 'A':
  114.         /*   Ambient light color: Red=0.3 Green=0.3 Blue=0.3 */
  115.         /* Ignore for now */
  116.         break;
  117.  
  118.         case 'B':
  119.         /*   Background solid color: Red=0 Green=0.105882 Blue=0.32549 */
  120.         if (strstr (string, "Background solid") && format == POV) {
  121.             red   = atof (between (string, "Red=", "Green="));
  122.             green = atof (between (string, "Green=", "Blue="));
  123.             blue  = atof (after   (string, "Blue="));
  124.  
  125.             if (red > 0.0 || green > 0.0 || blue > 0.0) {
  126.             fprintf (out, "/* Background colour */\n");
  127.             fprintf (out, "object\n");
  128.             fprintf (out, "   sphere <0.0 0.0 0.0> 1e6 end_sphere\n");
  129.             fprintf (out, "   texture\n");
  130.             fprintf (out, "      ambient 1.0 diffuse 0.0\n");
  131.             fprintf (out, "      colour red %4.2f green %4.2f blue %4.2f\n",
  132.                          red, green, blue);
  133.             fprintf (out, "   end_texture\n");
  134.             fprintf (out, "end_object\n\n");
  135.             }
  136.         }
  137.  
  138.         /*  Bank angle: 0.00 degrees */
  139.  
  140.         /*  Background dimmed */
  141.  
  142.         break;
  143.  
  144.         case 'C':
  145.         /*   Camera (50.000000mm) */
  146.         if (strstr (string, "Camera") && format == POV) {
  147.             lens = atof (between (string, "(", "mm)"));
  148.  
  149.             if (lens <= 0.0)
  150.             lens = 16.0;
  151.  
  152.             fprintf(out,"view_point\n");
  153.             fprintf(out,"   location <0.0 0.0 0.0>\n");
  154.         }
  155.  
  156.         break;
  157.  
  158.         case 'D':
  159.         /*   Direct light     */
  160.         if (strstr (string, "Direct") && format == POV) {
  161.             fprintf(out,"object\n");
  162.             fprintf(out,"   sphere <0.0 0.0 0.0> 1.0 end_sphere\n");
  163.         }
  164.  
  165.         /* Distance-cueing: */
  166.  
  167.         break;
  168.  
  169.         case 'F':
  170.         /*   Face 0:    A:0 B:1 C:109 Mtl:CHROME */
  171.         if (strstr (string, "Face") && strstr (string, "Mtl")) {
  172.             face_number = atoi (between (string, "Face", ":"));
  173.  
  174.             a = atoi (between (string, "A:", "B:"));
  175.             b = atoi (between (string, "B:", "C:"));
  176.             c = atoi (between (string, "C:", "Mtl:"));
  177.  
  178.             strcpy (mtl, after (string, "Mtl:"));
  179.             cleanup_name (mtl);
  180.  
  181.             if (format == POV) {
  182.             update_materials (mtl);
  183.  
  184.             opt_set_texture (mtl);
  185.             opt_add_tri (coords[a].x, coords[a].y, coords[a].z,
  186.                      coords[b].x, coords[b].y, coords[b].z,
  187.                      coords[c].x, coords[c].y, coords[c].z);
  188.  
  189.             if (face_number == faces-1) {
  190.                 fclose (out);
  191.                 opt_write_pov (object);
  192.                 out = fopen (outname, "a");
  193.  
  194.                 ++objects;
  195.  
  196.                 farfree ((void far *)coords);
  197.             }
  198.             }
  199.             else if (format == RAW) {
  200.             fprintf (out, "%f %f %f   %f %f %f   %f %f %f\n",
  201.                       coords[a].x, coords[a].y, coords[a].z,
  202.                       coords[b].x, coords[b].y, coords[b].z,
  203.                       coords[c].x, coords[c].y, coords[c].z);
  204.             }
  205.         }
  206.  
  207.         /*  Face list: */
  208.  
  209.         /*  Falloff size: 18.25 degrees */
  210.  
  211.         /*  Far plane: 2113.823486    Far Dimming: 100 */
  212.  
  213.         break;
  214.  
  215.  
  216.         case 'L':
  217.         /*   Light color: Red=0.32 Green=0.9 Blue=0.72 */
  218.         if (strstr (string, "Light color") && format == POV) {
  219.             red   = atof (between (string, "Red=", "Green="));
  220.             green = atof (between (string, "Green=", "Blue="));
  221.             blue  = atof (after   (string, "Blue="));
  222.  
  223.             fprintf (out,"   colour red %4.2f green %4.2f blue %4.2f\n",red,green,blue);
  224.             fprintf (out,"   texture\n");
  225.             fprintf (out,"       ambient 1.0\n");
  226.             fprintf (out,"       diffuse 0.0\n");
  227.             fprintf (out,"       colour red %4.2f green %4.2f blue %4.2f\n",red,green,blue);
  228.             fprintf (out,"   end_texture\n");
  229.             fprintf (out,"   light_source\n");
  230.             fprintf (out,"end_object\n\n");
  231.         }
  232.  
  233.         break;
  234.  
  235.         case 'N':
  236.         /*   Named object: teacup   */
  237.         if (strstr (string, "Named")) {
  238.             strcpy (object, after (string, ":"));
  239.             cleanup_name (object);
  240.             printf ("Working on: %s\n",object);
  241.  
  242.             if (format == RAW)
  243.             fprintf (out, "; %s\n", object);
  244.         }
  245.  
  246.         /* Near plane: 1728.713379   Near Dimming: 0 */
  247.  
  248.         break;
  249.  
  250.         case 'P':
  251.         /*   Position:  X:298.177734 Y:-314.924225 Z:182.459198 */
  252.         if (strstr (string, "Position") && format == POV) {
  253.             x = atof (between (string, "X:", "Y:"));
  254.             y = atof (between (string, "Y:", "Z:"));
  255.             z = atof (after   (string, "Z:"));
  256.  
  257.             fprintf (out,"   translate <%11.6f %11.6f %11.6f>\n", x,y,z);
  258.         }
  259.  
  260.         break;
  261.  
  262.         case 'S':
  263.         /*   Smoothing:  1, 10 */
  264.         /* don't know what it means */
  265.  
  266.         /*  Spotlight to:  X:-98.558777 Y:-176.971039 Z:-363.822357 */
  267.         /* Could be synthesized, flaming terror */
  268.  
  269.         break;
  270.  
  271.  
  272.         case 'T':
  273.         /*   Target:  X:79.31871 Y:-11.135715 Z:27.661964 */
  274.         if (strstr(string,"Target:") && format == POV) {
  275.             tx = atof (between (string, "X:", "Y:"));
  276.             ty = atof (between (string, "Y:", "Z:"));
  277.             tz = atof (after   (string, "Z:"));
  278.  
  279.             fprintf (out, "   direction <0 %6.2f 0>\n", (lens/35.0));
  280.             fprintf (out, "   up <0 0 1>\n");
  281.             fprintf (out, "   sky  <0 0 1>\n");
  282.             fprintf (out, "   right <1.33 0 0>\n");
  283.             fprintf (out, "   look_at <%11.6f %11.6f %11.6f>\n", tx,ty,tz);
  284.             fprintf (out, "end_view_point\n\n");
  285.         }
  286.  
  287.         /*   Tri-mesh, Vertices: 3240     Faces: 6480 */
  288.         if (strstr (string, "Tri-mesh")) {
  289.             vertices = atoi (between (string, "Vertices:", "Faces:"));
  290.             faces    = atoi (after   (string, "Faces:"));
  291.  
  292.             if ((coords = farmalloc ((long)vertices * sizeof(Vector)))==NULL)
  293.             abortmsg ("Insufficient memory for coordinates.", 1);
  294.         }
  295.  
  296.         break;
  297.  
  298.         case 'V':
  299.         /*   Vertex 0:  X: 82.320801     Y: -15.238132     Z: 28.071295 */
  300.         if (strstr (string, "Vertex") && strstr (string, "X:")) {
  301.             vertex_number = atoi (between (string, "Vertex", ":"));
  302.  
  303.             coords[vertex_number].x = atof (between (string, "X:", "Y:"));
  304.             coords[vertex_number].y = atof (between (string, "Y:", "Z:"));
  305.             coords[vertex_number].z = atof (after   (string, "Z:"));
  306.         }
  307.  
  308.         /*  Vertex list: */
  309.  
  310.         break;
  311.  
  312.         default:    /*   Blank lines, page numbers...  */
  313.         break;
  314.     }
  315.     }
  316.  
  317.     if (format == POV) {
  318.     for (i = 0; i < materials; i++) {
  319.         fprintf (out, "#declare %s = texture\n", material[i]);
  320.         fprintf (out, "    DefTexture\n");
  321.         fprintf (out, "    color White\n");
  322.         fprintf (out, "end_texture\n\n");
  323.  
  324.         free (material[i]);
  325.     }
  326.  
  327.     fprintf (out, "composite   /* All Objects */\n    ");
  328.  
  329.     fclose (out);
  330.     opt_finish();
  331.     out = fopen (outname, "a");
  332.  
  333.     if (out == NULL)
  334.         abortmsg ("Error opening output file", 1);
  335.  
  336.     opt_get_glimits (&gmin_x, &gmin_y, &gmin_z, &gmax_x, &gmax_y, &gmax_z);
  337.  
  338.     if (objects > 2) {
  339.         fprintf (out, "\n");
  340.         fprintf (out, "    bounded_by\n");
  341.         fprintf (out, "\tintersection\n");
  342.         fprintf (out, "\t   plane <+1 0 0> %.4f end_plane\n", +gmax_x);
  343.         fprintf (out, "\t   plane <-1 0 0> %.4f end_plane\n", -gmin_x);
  344.         fprintf (out, "\t   plane <0 +1 0> %.4f end_plane\n", +gmax_y);
  345.         fprintf (out, "\t   plane <0 -1 0> %.4f end_plane\n", -gmin_y);
  346.         fprintf (out, "\t   plane <0 0 +1> %.4f end_plane\n", +gmax_z);
  347.         fprintf (out, "\t   plane <0 0 -1> %.4f end_plane\n", -gmin_z);
  348.         fprintf (out, "\tend_intersection\n");
  349.         fprintf (out, "    end_bound\n");
  350.     }
  351.  
  352.     fprintf (out, "\n");
  353.     fprintf (out, "    /*\n");
  354.     fprintf (out, "        Scene extents\n");
  355.     fprintf (out, "        X - Min: %8.4f  Max: %8.4f\n", gmin_x, gmax_x);
  356.     fprintf (out, "        Y - Min: %8.4f  Max: %8.4f\n", gmin_y, gmax_y);
  357.     fprintf (out, "        Z - Min: %8.4f  Max: %8.4f\n", gmin_z, gmax_z);
  358.     fprintf (out, "    */\n");
  359.  
  360.     fprintf (out, "end_composite\n\n");
  361.     }
  362.  
  363.     fclose(in);
  364.     fclose(out);
  365.  
  366.     return 0;
  367. }
  368.  
  369.  
  370.  
  371. void process_args (int argc, char *argv[])
  372. {
  373.     int i;
  374.  
  375.     printf("\n\nAutoDesk 3D Studio to PoV .DATa file Translator. May/92\n");
  376.     printf("Version 1.2 Copyright (c) 1992 Steve Anger and Jeff Bowermaster\n");
  377.     printf ("\n");
  378.  
  379.     if (argc < 2) {
  380.     printf ("Usage: 3ds2pov inputfile[.asc] [outputfile[.dat]] [[-/]options]\n\n");
  381.     printf ("Options: -snnn  - Smooth triangles with angles < nnn\n");
  382.     printf ("         -b     - Use box as bounding shape instead of ellipsoid.\n");
  383.     printf ("         -u     - Do not add nested bounds to output (unbounded)\n");
  384.     printf ("         -v     - Verbose status messages\n");
  385.     printf ("         -r     - Output to RAW triangle format\n");
  386.     printf ("\nex. 3ds2pov birdshow.asc birdshow.dat -s60 -v\n\n");
  387.     exit(1);
  388.     }
  389.  
  390.     strcpy (inname, "");
  391.     strcpy (outname, "");
  392.     smooth = 0.0;
  393.     bound = 0;
  394.     verbose = 0;
  395.     format = POV;
  396.  
  397.     for (i = 1; i < argc; i++) {
  398.     if (argv[i][0] == '-' || argv[i][0] == '/') {
  399.         switch (argv[i][1]) {
  400.         case 'B':
  401.         case 'b': bound = 1;
  402.               break;
  403.  
  404.         case 'R':
  405.         case 'r': format = RAW;
  406.               break;
  407.  
  408.         case 'U':
  409.         case 'u': bound = 2;
  410.               break;
  411.  
  412.         case 'V':
  413.         case 'v': verbose = 1;
  414.               break;
  415.  
  416.         case 'S':
  417.         case 's': if (argv[i][2] == '\0')
  418.                   smooth = 60.0;
  419.               else
  420.                   sscanf (&argv[i][2], "%f", &smooth);
  421.               break;
  422.  
  423.         default : printf ("\nInvalid option -%c\n", argv[i][1]);
  424.               exit (1);
  425.         }
  426.     }
  427.     else if (strlen (inname) == 0) {
  428.         strcpy (inname, argv[i]);
  429.         add_ext (inname, "asc", 0);
  430.     }
  431.     else if (strlen (outname) == 0) {
  432.         strcpy (outname, argv[i]);
  433.  
  434.         switch (format) {
  435.         case POV: add_ext (outname, "dat", 0); break;
  436.         case RAW: add_ext (outname, "raw", 0); break;
  437.         }
  438.     }
  439.     else
  440.         abortmsg ("Too many file names specified.\n", 1);
  441.     }
  442.  
  443.     if (strlen(outname) == 0) {
  444.     strcpy (outname, inname);
  445.  
  446.     switch (format) {
  447.         case POV: add_ext (outname, "dat", 1); break;
  448.         case RAW: add_ext (outname, "raw", 1); break;
  449.     }
  450.     }
  451. }
  452.  
  453.  
  454. void update_materials (char *new_material)
  455. {
  456.     int  i;
  457.  
  458.     for (i = 0; i < materials; i++) {
  459.     if (strcmp (new_material, material[i]) == 0)
  460.         break;
  461.     }
  462.  
  463.     if (i < materials)
  464.     return;
  465.  
  466.     if (i == MAX_MATERIAL)
  467.     abortmsg ("Too many materials", 1);
  468.  
  469.     material[i] = malloc (strlen (new_material) + 1);
  470.     strcpy (material[i], new_material);
  471.  
  472.     ++materials;
  473. }
  474.  
  475.  
  476. char *before (char *str, char *target)
  477. {
  478.     static char result[256];
  479.     char   *search;
  480.  
  481.     strncpy (result, str, 256);
  482.     result[255] = '\0';
  483.  
  484.     search = strstr (result, target);
  485.  
  486.     if (search != NULL)
  487.     *search = '\0';
  488.  
  489.     return result;
  490. }
  491.  
  492.  
  493. char *after (char *str, char *target)
  494. {
  495.     static char result[256];
  496.     char   *search;
  497.  
  498.     search = strstr (str, target);
  499.  
  500.     if (search == NULL)
  501.     strncpy (result, "", 256);
  502.     else
  503.     strncpy (result, search + strlen(target), 256);
  504.  
  505.     result[255] = '\0';
  506.  
  507.     return result;
  508. }
  509.  
  510.  
  511. char *between (char *str, char *target1, char *target2)
  512. {
  513.     static char result[256];
  514.  
  515.     strcpy (result, after (str, target1));
  516.     strcpy (result, before (result, target2));
  517.  
  518.     return result;
  519. }
  520.  
  521.